<template><div><h2 id="eloquent-api-resources" tabindex="-1"><a class="header-anchor" href="#eloquent-api-resources"><span>Eloquent: API Resources</span></a></h2>
<ul>
<li><a href="#introduction">简介</a></li>
<li><a href="#generating-resources">生成资源</a></li>
<li><a href="#concept-overview">生成资源</a>
<ul>
<li><a href="#resource-collections">资源集合</a></li>
</ul>
</li>
<li><a href="#writing-resources">编写资源</a>
<ul>
<li><a href="#data-wrapping">数据包裹</a></li>
<li><a href="#pagination">分页</a></li>
<li><a href="#conditional-attributes">条件属性</a></li>
<li><a href="#conditional-relationships">条件关系</a></li>
<li><a href="#adding-meta-data">添加元数据</a></li>
</ul>
</li>
<li><a href="#resource-responses">资源响应</a></li>
</ul>
<h2 id="简介" tabindex="-1"><a class="header-anchor" href="#简介"><span>简介</span></a></h2>
<p>在构建 API 时，你往往需要一个转换层来联结你的 Eloquent 模型和实际返回给用户的 JSON 响应。比如，你可能希望显示部分用户属性而不是全部，或者你可能希望在模型的 JSON 中包括某些关系。Eloquent 的资源类能够让你以更直观简便的方式将模型和模型集合转化成 JSON。</p>
<p>当然，你可以始终使用 Eloquent 模型或集合的 <code v-pre>toJson</code> 方法将其转换为 JSON ；但是，Eloquent 的资源提供了对模型及其关系的 JSON 序列化更加精细和更加健壮的控制。</p>
<h2 id="生成资源" tabindex="-1"><a class="header-anchor" href="#生成资源"><span>生成资源</span></a></h2>
<p>你可以使用 <code v-pre>make:resource</code> artisan 命令来生成一个资源类。默认情况下，资源将放在应用程序的 <code v-pre>app/Http/Resources</code> 目录下。资源继承自 <code v-pre>Illuminate\Http\Resources\Json\JsonResource</code> 类：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan make:resource UserResource</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="资源集合" tabindex="-1"><a class="header-anchor" href="#资源集合"><span>资源集合</span></a></h4>
<p>除了生成转换单个模型的资源之外，还可以生成负责转换模型集合的资源。这允许你的 JSON 包含与给定资源的整个集合相关的其他信息。</p>
<p>你应该在创建资源集合时使用 <code v-pre>--collection</code> 标志来表明你要生成一个资源集合。或者，在资源名称中包含 Collection 一词将向 Laravel 表明它应该生成一个资源集合。资源集合继承自 <code v-pre>Illuminate\Http\Resources\Json\ResourceCollection</code> 类：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan make:resource User <span class="token parameter variable">--collection</span></span>
<span class="line"></span>
<span class="line">php artisan make:resource UserCollection</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="概念综述" tabindex="-1"><a class="header-anchor" href="#概念综述"><span>概念综述</span></a></h2>
<blockquote>
<p><strong>提示</strong><br>
提示：这是对资源和资源集合的高度概述。强烈建议您阅读本文档的其他部分，以深入了解如何更好地自定义和使用资源。</p>
</blockquote>
<p>在深入了解如何定制化编写你的资源之前，让我们首先从高层次上了解 Laravel 中如何使用资源。一个资源类表示一个单一模型需要被转换成 JSON 格式。例如，下面是一个简单的 <code v-pre>UserResource</code> 资源类：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Request</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>Json<span class="token punctuation">\</span>JsonResource</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">UserResource</span> <span class="token keyword">extends</span> <span class="token class-name">JsonResource</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 将资源转换为数组。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">email</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'created_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">created_at</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'updated_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">updated_at</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>每个资源类都定义了一个 <code v-pre>toArray</code> 方法，当资源从路由或控制器方法作为响应被调用返回时，该方法返回应该转换为 JSON 的属性数组。</p>
<p>注意，我们可以直接使用 <code v-pre>$this</code> 变量访问模型属性。这是因为资源类将自动代理属性和方法访问到底层模型以方便访问。一旦定义了资源，你可以从路由或控制器中调用并返回它。资源通过其构造函数接受底层模型实例：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>UserResource</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/user/{id}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token keyword type-hint">string</span> <span class="token variable">$id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">UserResource</span><span class="token punctuation">(</span><span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">findOrFail</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="资源集合-1" tabindex="-1"><a class="header-anchor" href="#资源集合-1"><span>资源集合</span></a></h3>
<p>如果你要返回一个资源集合或一个分页响应，你应该在路由或控制器中创建资源实例时使用你的资源类提供的 <code v-pre>collection</code> 方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>UserResource</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/users'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token class-name static-context">UserResource</span><span class="token operator">::</span><span class="token function">collection</span><span class="token punctuation">(</span><span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>当然了，使用如上方法你将不能添加任何附加的元数据和集合一起返回。如果你需要自定义资源集合响应，你需要创建一个专用的资源来表示集合：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan make:resource UserCollection</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>此时，你就可以轻松地自定义响应中应该包含的任何元数据：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Request</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>Json<span class="token punctuation">\</span>ResourceCollection</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">UserCollection</span> <span class="token keyword">extends</span> <span class="token class-name">ResourceCollection</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 将资源集合转换为数组。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;int|string, mixed></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'data'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">collection</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'links'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'self'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'link-value'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你可以在路由或者控制器中返回已定义的资源集合：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>UserCollection</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/users'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">UserCollection</span><span class="token punctuation">(</span><span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="保护集合的键" tabindex="-1"><a class="header-anchor" href="#保护集合的键"><span>保护集合的键</span></a></h4>
<p>当从路由返回一个资源集合时，Laravel 会重置集合的键，使它们按数字顺序排列。但是，你可以在资源类中添加 <code v-pre>preserveKeys</code> 属性，以指示是否应该保留集合的原始键：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>Json<span class="token punctuation">\</span>JsonResource</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">UserResource</span> <span class="token keyword">extends</span> <span class="token class-name">JsonResource</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 指示是否应保留资源的集合原始键。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@var</span> <span class="token class-name"><span class="token keyword">bool</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token variable">$preserveKeys</span> <span class="token operator">=</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果 <code v-pre>preserveKeys</code> 属性设置为 <code v-pre>true</code> ，那么从路由或控制器返回集合时，集合的键将会被保留：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>UserResource</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/users'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token class-name static-context">UserResource</span><span class="token operator">::</span><span class="token function">collection</span><span class="token punctuation">(</span><span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token property">keyBy</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="自定义基础资源类" tabindex="-1"><a class="header-anchor" href="#自定义基础资源类"><span>自定义基础资源类</span></a></h4>
<p>通常，资源集合的 <code v-pre>$this-&gt;collection</code> 属性会被自动填充，结果是将集合的每个项映射到其单个资源类。单个资源类被假定为资源的类名，但没有类名末尾的 <code v-pre>Collection</code> 部分。 此外，根据您的个人偏好，单个资源类可以带着后缀 <code v-pre>Resource</code> ，也可以不带。</p>
<p>例如，<code v-pre>UserCollection</code> 会尝试将给定的用户实例映射到 <code v-pre>User</code> 或 <code v-pre>UserResource</code> 资源。想要自定义该行为，你可以重写资源集合中的 <code v-pre>$collects</code> 属性指定自定义的资源：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>Json<span class="token punctuation">\</span>ResourceCollection</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">UserCollection</span> <span class="token keyword">extends</span> <span class="token class-name">ResourceCollection</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 自定义资源类名。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@var</span> <span class="token class-name"><span class="token keyword">string</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token variable">$collects</span> <span class="token operator">=</span> <span class="token class-name static-context">Member</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="编写资源" tabindex="-1"><a class="header-anchor" href="#编写资源"><span>编写资源</span></a></h2>
<blockquote>
<p><strong>Note</strong><br>
技巧：如果您还没有阅读 <a href="#concept-overview">概念综述</a>，那么在继续阅读本文档前，强烈建议您去阅读一下，会更容易理解本节的内容。</p>
</blockquote>
<p>从本质上说，资源的作用很简单，它只需将一个给定的模型转换为一个数组。因此，每个资源都包含一个 <code v-pre>toArray</code> 方法，这个方法会将模型的属性转换为一个 API 友好的数组，然后将该数组通过路由或控制器返回给用户：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Request</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>Json<span class="token punctuation">\</span>JsonResource</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">UserResource</span> <span class="token keyword">extends</span> <span class="token class-name">JsonResource</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 将资源转换为数组。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">email</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'created_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">created_at</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'updated_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">updated_at</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>一旦资源被定义，它可以直接从路由或控制器返回：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>UserResource</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/user/{id}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token keyword type-hint">string</span> <span class="token variable">$id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">UserResource</span><span class="token punctuation">(</span><span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">findOrFail</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="关联关系" tabindex="-1"><a class="header-anchor" href="#关联关系"><span>关联关系</span></a></h4>
<p>如果你想在你的响应中包含关联的资源，你可以将它们添加到你的资源的 <code v-pre>toArray</code> 方法返回的数组中。在下面的例子中，我们将使用 <code v-pre>PostResource</code> 资源的 <code v-pre>collection</code> 方法来将用户的博客文章添加到资源响应中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>PostResource</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Request</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 将资源转换为数组。</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">email</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'posts'</span> <span class="token operator">=></span> <span class="token class-name static-context">PostResource</span><span class="token operator">::</span><span class="token function">collection</span><span class="token punctuation">(</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">posts</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'created_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">created_at</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'updated_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">updated_at</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>注意：如果你只希望在已经加载的关联关系中包含它们，点这里查看 <a href="#conditional-relationships">条件关联</a>。</p>
</blockquote>
<h4 id="资源集合-2" tabindex="-1"><a class="header-anchor" href="#资源集合-2"><span>资源集合</span></a></h4>
<p>当资源将单个模型转换为数组时，资源集合将模型集合转换为数组。当然，你并不是必须要为每个类都定义一个资源集合类，因为所有的资源都提供了一个 <code v-pre>collection</code> 方法来动态地生成一个「临时」资源集合：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>UserResource</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/users'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token class-name static-context">UserResource</span><span class="token operator">::</span><span class="token function">collection</span><span class="token punctuation">(</span><span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>当然，如果你需要自定义资源集合返回的元数据，那就需要自己创建资源集合类：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>Json<span class="token punctuation">\</span>ResourceCollection</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">UserCollection</span> <span class="token keyword">extends</span> <span class="token class-name">ResourceCollection</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 将资源集合转换为数组。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'data'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">collection</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'links'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'self'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'link-value'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>和单个资源一样，你可以在路由或控制器中直接返回资源集合：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>UserCollection</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/users'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">UserCollection</span><span class="token punctuation">(</span><span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="数据包裹" tabindex="-1"><a class="header-anchor" href="#数据包裹"><span>数据包裹</span></a></h3>
<p>默认情况下，当资源响应被转换为 JSON 时，最外层的资源被包裹在 <code v-pre>data</code> 键中。因此一个典型的资源收集响应如下所示：</p>
<div class="language-json line-numbers-mode" data-highlighter="prismjs" data-ext="json" data-title="json"><pre v-pre class="language-json"><code><span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token property">"data"</span><span class="token operator">:</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token punctuation">{</span></span>
<span class="line">            <span class="token property">"id"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"Eladio Schroeder Sr."</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token property">"email"</span><span class="token operator">:</span> <span class="token string">"therese28@example.com"</span></span>
<span class="line">        <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">{</span></span>
<span class="line">            <span class="token property">"id"</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"Liliana Mayert"</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token property">"email"</span><span class="token operator">:</span> <span class="token string">"evandervort@example.com"</span></span>
<span class="line">        <span class="token punctuation">}</span></span>
<span class="line">    <span class="token punctuation">]</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果你想使用自定义键而不是 <code v-pre>data</code>，你可以在资源类上定义一个 <code v-pre>$wrap</code> 属性：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>Json<span class="token punctuation">\</span>JsonResource</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">UserResource</span> <span class="token keyword">extends</span> <span class="token class-name">JsonResource</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 应该应用的「数据」包装器。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@var</span> <span class="token class-name"><span class="token keyword">string</span><span class="token punctuation">|</span><span class="token keyword">null</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token variable">$wrap</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'user'</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果你想禁用最外层资源的包裹，你应该调用基类 <code v-pre>Illuminate\Http\Resources\Json\JsonResource</code> 的 <code v-pre>withoutWrapping</code> 方法。通常，你应该从你的 <code v-pre>AppServiceProvider</code> 或其他在程序每一个请求中都会被加载的 <a href="https://learnku.com/docs/laravel/10.x/providers" target="_blank" rel="noopener noreferrer">服务提供者</a> 中调用这个方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Providers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>Json<span class="token punctuation">\</span>JsonResource</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>ServiceProvider</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">AppServiceProvider</span> <span class="token keyword">extends</span> <span class="token class-name">ServiceProvider</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 注册任何应用程序服务。</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">register</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token comment">// ...</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 引导任何应用程序服务。</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token class-name static-context">JsonResource</span><span class="token operator">::</span><span class="token function">withoutWrapping</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p><strong>注意</strong><br>
<code v-pre>withoutWrapping</code> 方法只会禁用最外层资源的包裹，不会删除你手动添加到资源集合中的 <code v-pre>data</code> 键。</p>
</blockquote>
<h4 id="包裹嵌套资源" tabindex="-1"><a class="header-anchor" href="#包裹嵌套资源"><span>包裹嵌套资源</span></a></h4>
<p>你可以完全自由地决定资源关联如何被包裹。如果你希望无论怎样嵌套，所有的资源集合都包裹在一个 <code v-pre>data</code> 键中，你应该为每个资源定义一个资源集合类，并将返回的集合包裹在 <code v-pre>data</code> 键中。</p>
<p>你可能会担心这是否会导致最外层的资源包裹在两层 <code v-pre>data</code> 键中。别担心， Laravel 永远不会让你的资源被双层包裹，所以你不必担心资源集合被多重嵌套的问题：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>Json<span class="token punctuation">\</span>ResourceCollection</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">CommentsCollection</span> <span class="token keyword">extends</span> <span class="token class-name">ResourceCollection</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 将资源集合转换成数组。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'data'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">collection</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="数据包裹和分页" tabindex="-1"><a class="header-anchor" href="#数据包裹和分页"><span>数据包裹和分页</span></a></h4>
<p>当通过资源响应返回分页集合时，即使你调用了 <code v-pre>withoutWrapping</code> 方法，Laravel 也会将你的资源数据包裹在 <code v-pre>data</code> 键中。这是因为分页响应总会有 <code v-pre>meta</code> 和 <code v-pre>links</code> 键包含关于分页状态的信息：</p>
<div class="language-json line-numbers-mode" data-highlighter="prismjs" data-ext="json" data-title="json"><pre v-pre class="language-json"><code><span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token property">"data"</span><span class="token operator">:</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token punctuation">{</span></span>
<span class="line">            <span class="token property">"id"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"Eladio Schroeder Sr."</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token property">"email"</span><span class="token operator">:</span> <span class="token string">"therese28@example.com"</span></span>
<span class="line">        <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">{</span></span>
<span class="line">            <span class="token property">"id"</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"Liliana Mayert"</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token property">"email"</span><span class="token operator">:</span> <span class="token string">"evandervort@example.com"</span></span>
<span class="line">        <span class="token punctuation">}</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token property">"links"</span><span class="token operator">:</span><span class="token punctuation">{</span></span>
<span class="line">        <span class="token property">"first"</span><span class="token operator">:</span> <span class="token string">"http://example.com/pagination?page=1"</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"last"</span><span class="token operator">:</span> <span class="token string">"http://example.com/pagination?page=1"</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"prev"</span><span class="token operator">:</span> <span class="token null keyword">null</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"next"</span><span class="token operator">:</span> <span class="token null keyword">null</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token property">"meta"</span><span class="token operator">:</span><span class="token punctuation">{</span></span>
<span class="line">        <span class="token property">"current_page"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"from"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"last_page"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"path"</span><span class="token operator">:</span> <span class="token string">"http://example.com/pagination"</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"per_page"</span><span class="token operator">:</span> <span class="token number">15</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"to"</span><span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"total"</span><span class="token operator">:</span> <span class="token number">10</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="分页" tabindex="-1"><a class="header-anchor" href="#分页"><span>分页</span></a></h3>
<p>你可以将 Laravel 分页实例传递给资源的 <code v-pre>collection</code> 方法或自定义资源集合：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>UserCollection</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/users'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">UserCollection</span><span class="token punctuation">(</span><span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">paginate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>分页响应中总有 <code v-pre>meta</code> 和 <code v-pre>links</code> 键包含着分页状态信息：</p>
<div class="language-json line-numbers-mode" data-highlighter="prismjs" data-ext="json" data-title="json"><pre v-pre class="language-json"><code><span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token property">"data"</span><span class="token operator">:</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token punctuation">{</span></span>
<span class="line">            <span class="token property">"id"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"Eladio Schroeder Sr."</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token property">"email"</span><span class="token operator">:</span> <span class="token string">"therese28@example.com"</span></span>
<span class="line">        <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">{</span></span>
<span class="line">            <span class="token property">"id"</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"Liliana Mayert"</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token property">"email"</span><span class="token operator">:</span> <span class="token string">"evandervort@example.com"</span></span>
<span class="line">        <span class="token punctuation">}</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token property">"links"</span><span class="token operator">:</span><span class="token punctuation">{</span></span>
<span class="line">        <span class="token property">"first"</span><span class="token operator">:</span> <span class="token string">"http://example.com/pagination?page=1"</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"last"</span><span class="token operator">:</span> <span class="token string">"http://example.com/pagination?page=1"</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"prev"</span><span class="token operator">:</span> <span class="token null keyword">null</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"next"</span><span class="token operator">:</span> <span class="token null keyword">null</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token property">"meta"</span><span class="token operator">:</span><span class="token punctuation">{</span></span>
<span class="line">        <span class="token property">"current_page"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"from"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"last_page"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"path"</span><span class="token operator">:</span> <span class="token string">"http://example.com/pagination"</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"per_page"</span><span class="token operator">:</span> <span class="token number">15</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"to"</span><span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"total"</span><span class="token operator">:</span> <span class="token number">10</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="条件属性" tabindex="-1"><a class="header-anchor" href="#条件属性"><span>条件属性</span></a></h3>
<p>有些时候，你可能希望在给定条件满足时添加属性到资源响应里。例如，你可能希望如果当前用户是「管理员」时添加某个值到资源响应中。在这种情况下 Laravel 提供了一些辅助方法来帮助你解决问题。<code v-pre>when</code> 方法可以被用来有条件地向资源响应添加属性：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 将资源转换成数组。</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">email</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'secret'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">when</span><span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token function">user</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">isAdmin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'secret-value'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'created_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">created_at</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'updated_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">updated_at</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在上面这个例子中，只有当 <code v-pre>isAdmin</code> 方法返回 <code v-pre>true</code> 时，<code v-pre>secret</code> 键才会最终在资源响应中被返回。如果该方法返回 <code v-pre>false</code> 键将会在资源响应被发送给客户端之前被删除。 <code v-pre>when</code> 方法可以使你避免使用条件语句拼接数组，转而用更优雅的方式来编写你的资源。</p>
<p><code v-pre>when</code> 方法也接受闭包作为其第二个参数，只有在给定条件为 <code v-pre>true</code> 时，才从闭包中计算返回的值：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'secret'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">when</span><span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token function">user</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">isAdmin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token string single-quoted-string">'secret-value'</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code v-pre>whenHas</code> 方法可以用来包含一个属性，如果它确实存在于底层模型中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">whenHas</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'name'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>此外， <code v-pre>whenNotNull</code> 方法可用于在资源响应中包含一个属性，如果该属性不为空：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">whenNotNull</span><span class="token punctuation">(</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="有条件地合并数据" tabindex="-1"><a class="header-anchor" href="#有条件地合并数据"><span>有条件地合并数据</span></a></h4>
<p>有些时候，你可能希望在给定条件满足时添加多个属性到资源响应里。在这种情况下，你可以使用 <code v-pre>mergeWhen</code> 方法在给定的条件为 <code v-pre>true</code> 时将多个属性添加到响应中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 将资源转换成数组</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">email</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">mergeWhen</span><span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token function">user</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">isAdmin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'first-secret'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'value'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'second-secret'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'value'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'created_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">created_at</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'updated_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">updated_at</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>同理，如果给定的条件为 <code v-pre>false</code> 时，则这些属性将会在资源响应被发送给客户端之前被移除。</p>
<blockquote>
<p><strong>注意</strong><br>
<code v-pre>mergeWhen</code> 方法不应该被使用在混合字符串和数字键的数组中。此外，它也不应该被使用在不按顺序排列的数字键的数组中。</p>
</blockquote>
<h3 id="条件关联" tabindex="-1"><a class="header-anchor" href="#条件关联"><span>条件关联</span></a></h3>
<p>除了有条件地加载属性之外，你还可以根据模型关联是否已加载来有条件地在你的资源响应中包含关联。这允许你在控制器中决定加载哪些模型关联，这样你的资源可以在模型关联被加载后才添加它们。最终，这样做可以使你的资源轻松避免「N+1」查询问题。</p>
<p>如果属性确实存在于模型中，可以用<code v-pre>whenHas</code>来获取：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">whenHas</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'name'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>此外，<code v-pre>whenNotNull</code>可用于在资源响应中获取一个不为空的属性：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">whenNotNull</span><span class="token punctuation">(</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="有条件地合并数据-1" tabindex="-1"><a class="header-anchor" href="#有条件地合并数据-1"><span>有条件地合并数据</span></a></h4>
<p>有些时候，你可能希望在给定条件满足时添加多个属性到资源响应里。在这种情况下，你可以使用 <code v-pre>mergeWhen</code> 方法在给定的条件为 <code v-pre>true</code> 时将多个属性添加到响应中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 将资源转换成数组。</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">email</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">mergeWhen</span><span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token function">user</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">isAdmin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'first-secret'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'value'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'second-secret'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'value'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'created_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">created_at</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'updated_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">updated_at</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>同理，如果给定的条件为 <code v-pre>false</code> 时，则这些属性将会在资源响应被发送给客户端之前被移除。</p>
<blockquote>
<p><strong>注意</strong><br>
<code v-pre>mergeWhen</code> 方法不应该被使用在混合字符串和数字键的数组中。此外，它也不应该被使用在不按顺序排列的数字键的数组中。</p>
</blockquote>
<h3 id="条件关联-1" tabindex="-1"><a class="header-anchor" href="#条件关联-1"><span>条件关联</span></a></h3>
<p>除了有条件地加载属性之外，你还可以根据模型关联是否已加载来有条件地在你的资源响应中包含关联。这允许你在控制器中决定加载哪些模型关联，这样你的资源可以在模型关联被加载后才添加它们。最终，这样做可以使你的资源轻松避免「N+1」查询问题。</p>
<p>可以使用<code v-pre>whenLoaded</code>方法来有条件的加载关联。为了避免加载不必要的关联，此方法接受关联的名称而不是关联本身作为其参数：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>PostResource</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 将资源转换成数组。</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">email</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'posts'</span> <span class="token operator">=></span> <span class="token class-name static-context">PostResource</span><span class="token operator">::</span><span class="token function">collection</span><span class="token punctuation">(</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">whenLoaded</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'posts'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'created_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">created_at</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'updated_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">updated_at</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在上面这个例子中，如果关联没有被加载，则<code v-pre>posts</code>键将会在资源响应被发送给客户端之前被删除。</p>
<h4 id="条件关系计数" tabindex="-1"><a class="header-anchor" href="#条件关系计数"><span>条件关系计数</span></a></h4>
<p>除了有条件地包含关系之外，你还可以根据关系的计数是否已加载到模型上，有条件地包含资源响应中的关系「计数」:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">new</span> <span class="token function">UserResource</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token operator">-></span><span class="token function">loadCount</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'posts'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p><code v-pre>whenCounted</code>方法可用于在资源响应中有条件地包含关系的计数。该方法避免在关系计数不存在时不必要地包含属性:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 将资源转换为一个数组。</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">email</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'posts_count'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">whenCounted</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'posts'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'created_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">created_at</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'updated_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">updated_at</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在这个例子中，如果<code v-pre>posts</code>关系的计数还没有加载，<code v-pre>posts_count</code>键将在资源响应发送到客户端之前从资源响应中删除。</p>
<h4 id="条件中间表信息" tabindex="-1"><a class="header-anchor" href="#条件中间表信息"><span>条件中间表信息</span></a></h4>
<p>除了在你的资源响应中有条件地包含关联外，你还可以使用 <code v-pre>whenPivotLoaded</code> 方法有条件地从多对多关联的中间表中添加数据。<code v-pre>whenPivotLoaded</code> 方法接受的第一个参数为中间表的名称。第二个参数是一个闭包，它定义了在模型上如果中间表信息可用时要返回的值：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 将资源转换成数组。</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'expires_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">whenPivotLoaded</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'role_user'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">            <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">pivot</span><span class="token operator">-></span><span class="token property">expires_at</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果你的关联使用的是 <a href="https://learnku.com/docs/laravel/10.x/eloquent-relationships#defining-custom-intermediate-table-models" target="_blank" rel="noopener noreferrer">自定义中间表</a>，你可以将中间表模型的实例作为 <code v-pre>whenPivotLoaded</code> 方法的第一个参数:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'expires_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">whenPivotLoaded</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Membership</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">pivot</span><span class="token operator">-></span><span class="token property">expires_at</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果你的中间表使用的是 <code v-pre>pivot</code> 以外的访问器，你可以使用 <code v-pre>whenPivotLoadedAs</code> 方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 将资源转换成数组。</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'expires_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">whenPivotLoadedAs</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'subscription'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'role_user'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">            <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">subscription</span><span class="token operator">-></span><span class="token property">expires_at</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="添加元数据" tabindex="-1"><a class="header-anchor" href="#添加元数据"><span>添加元数据</span></a></h3>
<p>一些 JSON API 标准需要你在资源和资源集合响应中添加元数据。这通常包括资源或相关资源的 <code v-pre>links</code> ，或一些关于资源本身的元数据。如果你需要返回有关资源的其他元数据，只需要将它们包含在 <code v-pre>toArray</code> 方法中即可。例如在转换资源集合时你可能需要添加 <code v-pre>link</code> 信息：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 将资源转换成数组。</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'data'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">collection</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'links'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'self'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'link-value'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>当添加额外的元数据到你的资源中时，你不必担心会覆盖 Laravel 在返回分页响应时自动添加的 <code v-pre>links</code> 或 <code v-pre>meta</code> 键。你添加的任何其他 <code v-pre>links</code> 会与分页响应添加的 <code v-pre>links</code> 相合并。</p>
<h4 id="顶层元数据" tabindex="-1"><a class="header-anchor" href="#顶层元数据"><span>顶层元数据</span></a></h4>
<p>有时候，你可能希望当资源被作为顶层资源返回时添加某些元数据到资源响应中。这通常包括整个响应的元信息。你可以在资源类中添加 <code v-pre>with</code> 方法来定义元数据。此方法应返回一个元数据数组，当资源被作为顶层资源渲染时，这个数组将会被包含在资源响应中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>Json<span class="token punctuation">\</span>ResourceCollection</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">UserCollection</span> <span class="token keyword">extends</span> <span class="token class-name">ResourceCollection</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 将资源集合转换成数组。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token keyword static-context">parent</span><span class="token operator">::</span><span class="token function">toArray</span><span class="token punctuation">(</span><span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 返回应该和资源一起返回的其他数据数组。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">with</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'meta'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'key'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'value'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="构造资源时添加元数据" tabindex="-1"><a class="header-anchor" href="#构造资源时添加元数据"><span>构造资源时添加元数据</span></a></h4>
<p>你还可以在路由或者控制器中构造资源实例时添加顶层数据。所有资源都可以使用 <code v-pre>additional</code> 方法来接受应该被添加到资源响应中的数据数组：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">UserCollection</span><span class="token punctuation">(</span><span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">load</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'roles'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span></span>
<span class="line">                <span class="token operator">-></span><span class="token function">additional</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'meta'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                    <span class="token string single-quoted-string">'key'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'value'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="响应资源" tabindex="-1"><a class="header-anchor" href="#响应资源"><span>响应资源</span></a></h2>
<p>就像你知道的那样，资源可以直接在路由和控制器中被返回：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>UserResource</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/user/{id}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token keyword type-hint">string</span> <span class="token variable">$id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">UserResource</span><span class="token punctuation">(</span><span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">findOrFail</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>但有些时候，在发送给客户端前你可能需要自定义 HTTP 响应。你有两种办法。第一，你可以链式调用 <code v-pre>response</code> 方法。此方法将会返回 <code v-pre>Illuminate\Http\JsonResponse</code> 实例，允许你自定义响应头信息：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>UserResource</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/user'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">UserResource</span><span class="token punctuation">(</span><span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span></span>
<span class="line">                <span class="token operator">-></span><span class="token function">response</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">                <span class="token operator">-></span><span class="token function">header</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'X-Value'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'True'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>另外，你还可以在资源中定义一个 <code v-pre>withResponse</code> 方法。此方法将会在资源被作为顶层资源在响应时被调用：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>JsonResponse</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Request</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Resources<span class="token punctuation">\</span>Json<span class="token punctuation">\</span>JsonResource</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">UserResource</span> <span class="token keyword">extends</span> <span class="token class-name">JsonResource</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 将资源转换为数组。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;string, mixed></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">toArray</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 自定义响应信息。</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">withResponse</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">,</span> <span class="token class-name type-declaration">JsonResponse</span> <span class="token variable">$response</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$response</span><span class="token operator">-></span><span class="token function">header</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'X-Value'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'True'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>本译文仅用于学习和交流目的，转载请务必注明文章译者、出处、和本文链接<br>
我们的翻译工作遵照 <a href="https://learnku.com/docs/guide/cc4.0/6589" target="_blank" rel="noopener noreferrer">CC 协议</a>，如果我们的工作有侵犯到您的权益，请及时联系我们。</p>
</blockquote>
<hr>
<blockquote>
<p>原文地址：<a href="https://learnku.com/docs/laravel/10.x/eloquent-resources/14892" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/10.x/el...</a></p>
<p>译文地址：<a href="https://learnku.com/docs/laravel/10.x/eloquent-resources/14892" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/10.x/el...</a></p>
</blockquote>
</div></template>


